
cmspad.apply(cmspad.validator, {
	initialize: function(f){
		var elements = f.elements;
		for (i = 0, l = elements.length; i < l; i++) {
			var element = elements[i];
			if (!element.isBindSet) {
				switch (element.type.toLowerCase()) {
					case 'select':
					case 'select-multiple':
						element.onchange = function(e){
							if (element.isBindDisabled) {
								return;
							}
							var bind = cmspad.validator._getBindData(this);
							if (bind) {
								cmspad.validator._validate(this, bind);
							}
						};
						break;
					case 'text':
					case 'file':
					case 'hidden':
					case 'textarea':
						element.onblur = function(){
							if (element.isBindDisabled) {
								return;
							}
							var bind = cmspad.validator._getBindData(this);
							if (bind) {
								cmspad.validator._validate(this, bind);
							}
						};
						break;
					case 'radio':
					case 'checkbox':
						element.onclick = function(e){
							if (element.isBindDisabled) {
								return;
							}
							var bind = cmspad.validator._getBindData(this);
							if (bind) {
								cmspad.validator._validate(this, bind);
							}
						};
						break;
				}
			}
		}
	},
	_validator_regexp: new RegExp('\s*([!]?[0-9a-zA-Z_]+)\s*[\(]{0,1}\s*([^\(\):]*)\s*[\)]{0,1}\s*[:]{0,1}\s*(.*)\s*'),
	_getExprData: function(b){
		var rs = [];
		var es = b.replace(/(^[;]+)|([;]+$)/g, '').split(';');
		for (var i in es) {
			var e = es[i];
			if (e.indexOf('.') > 0) {
				// It is a server expression.
				var bind = cmspad.core.getExprData(e, false);
				if (bind) {
					rs.push({
						type: 's',
						name: bind.portlet,
						args: bind.arguments,
						message: bind.validator
					});
				}
			} else {
				// It is a client expression.
				var regexp = this._validator_regexp.exec(e);
				rs.push({
					type: 'c',
					name: regexp[1],
					args: regexp[2],
					message: regexp[3]
				});
			}
		}
		return rs;
	},
	_getBindData: function(e){
		var b = e.getAttribute('bind');
		if (b) {
			return this._getExprData(b);
		} else {
			return null;
		}
	},
	_validate: function(e, ms){
	
		var tagType = e.type.toLowerCase();
		switch (tagType) {
			case 'radio':
			case 'checkbox':
				var v = [];
				var elements = e.form.elements;
				for (i = 0, l = elements.length; i < l; i++) {
					var element = elements[i];
					if (element.name == e.name && element.checked == true) {
						tagValue.push(element.value);
					}
				}
				break;
			case 'select-multiple':
				var v = [];
				for (var j = 0; j < e.length; j++) {
					if (e.options[j].selected == true) {
						tagValue.push(e.option[j].value);
					}
				}
				break;
			default:
				var v = e.value;
				break;
		}
		
		for (var i in ms) {
			var m = ms[i];
			switch (m.type) {
				case 'c':
					if (m.name.indexOf('!') == 0) {
						var p = '!';
						m.name = m.name.substring(1);
					} else {
						var p = '';
					}
					if(m.args){
						var a = ',' + m.args;
					}else{
						var a = '';
					}
					eval('var r = cmspad.validator._' + m.name + '?' + p + 'cmspad.validator._' + m.name + '(v' + a + '):true;');
					if (r === false) {
						e.isBindDisabled = true;
						switch (tagType) {
							case 'select':
								e.setSelectedIndex(0);
								break;
							case 'select-multiple':
								e.setSelectedIndex(-1);
								break;
							default:
								e.value = '';
								break;
						}
						e.isBindDisabled = false;
						if (m.message) {
							alert(m.message);
						}
						return false;
					}
					break;
				case 's':
					//20080626: 增加当进行服务器验证时先调用本地JS代码进行互动
					if(m.message){
						eval(m.message);
					}
					//:~
					cmspad_check(m.name, e.name, v);
					break;
			}
		}
	}
});